package log

import (
	"fmt"
	"log"
	"time"

	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
)

var (
	//日志级别
	logLevel LogLevel

	loggerTrace   *log.Logger
	loggerDebug   *log.Logger
	loggerInfo    *log.Logger
	loggerWarning *log.Logger
	loggerError   *log.Logger

	defaultSetting = RotationSetting{
		//level: InfoLevel
		path:   "./",
		format: "%Y%m%d_%H.log",
		size:   100 * 1024 * 1024,
		time:   time.Hour,
		age:    7 * 24 * time.Hour,
	}
)

//Init 简单初始化系统日志，只需要制定日志保存路径
func Init(level LogLevel, optionList ...RotationOption) {
	//日志级别作用于全局，不要放在RotationSetting里
	logLevel = level

	//处理文件滚动相关设置
	setting := defaultSetting
	for _, v := range optionList {
		v(&setting)
	}

	//为不同级别日志设立独立的文件夹
	pathTrace := setting.path + "Trace/"
	pathDebug := setting.path + "Debug/"
	pathInfo := setting.path + "Info/"
	pathWarning := setting.path + "Warning/"
	pathError := setting.path + "Error/"

	loggerTrace = loggerInit(pathTrace, "Trace - ", setting)
	loggerDebug = loggerInit(pathDebug, "Debug - ", setting)
	loggerInfo = loggerInit(pathInfo, "Info - ", setting)
	loggerWarning = loggerInit(pathWarning, "Warning - ", setting)
	loggerError = loggerInit(pathError, "Error - ", setting)
}

func Logger() *log.Logger {
	switch logLevel {
	case TraceLevel:
		return loggerTrace
	case DebugLevel:
		return loggerDebug
	case InfoLevel:
		return loggerInfo
	case WarningLevel:
		return loggerWarning
	case ErrorLevel:
		return loggerError
	default:
		return nil
	}
}

func loggerInit(levelLogPath, prefix string, model RotationSetting) (logger *log.Logger) {
	writer, err := rotatelogs.New(
		levelLogPath+model.format,
		rotatelogs.WithLinkName(levelLogPath),
		rotatelogs.WithRotationSize(model.size),
		rotatelogs.WithRotationTime(model.time),
		rotatelogs.WithMaxAge(model.age),
	)
	if err != nil {
		fmt.Println("日志初始化失败：" + err.Error())
		panic(err)
	}
	logger = log.New(writer, prefix, log.LstdFlags|log.Ldate|log.Llongfile)
	return
}

// func WithLogLevel(logLevel LogLevel) RotationOption {
// 	return func(setting *RotationSetting) {
// 		setting.level = logLevel
// 	}
// }

func WithLogPath(logPath string) RotationOption {
	return func(setting *RotationSetting) {
		setting.path = logPath
	}
}

func WithNameFormat(nameFormat string) RotationOption {
	return func(setting *RotationSetting) {
		setting.format = nameFormat
	}
}

func WithRotationSize(rotationSize int64) RotationOption {
	return func(setting *RotationSetting) {
		setting.size = rotationSize
	}
}

func WithRotationTime(rotationTime time.Duration) RotationOption {
	return func(setting *RotationSetting) {
		setting.time = rotationTime
	}
}
func WithMaxAge(maxAge time.Duration) RotationOption {
	return func(setting *RotationSetting) {
		setting.age = maxAge
	}
}

//Trace ...
func Trace(msg string) {
	if logLevel <= TraceLevel {
		loggerTrace.Println(msg)
		fmt.Println("Trace: " + msg)
	}
}

//Debug ...
func Debug(msg string) {
	if logLevel <= DebugLevel {
		loggerDebug.Println(msg)
		fmt.Println("Debug: " + msg)
	}
}

//Info ...
func Info(msg string) {
	if logLevel <= InfoLevel {
		loggerInfo.Println(msg)
		fmt.Println("Info: " + msg)
	}
}

//Warning ...
func Warning(msg string) {
	if logLevel <= WarningLevel {
		loggerWarning.Println(msg)
		fmt.Println("Warning: " + msg)
	}
}

//Error ...
func Error(msg string) {
	if logLevel <= ErrorLevel {
		loggerError.Println(msg)
		fmt.Println("Error: " + msg)
	}
}
